home *** CD-ROM | disk | FTP | other *** search
/ Languguage OS 2 / Languguage OS II Version 10-94 (Knowledge Media)(1994).ISO / gnu / libg_261.zip / libg_261 / libg++ / src / CursesW.cc < prev    next >
C/C++ Source or Header  |  1993-10-24  |  5KB  |  254 lines

  1. /* 
  2. Copyright (C) 1989, 1992 Free Software Foundation
  3.     written by Eric Newton (newton@rocky.oswego.edu)
  4.  
  5. This file is part of the GNU C++ Library.  This library is free
  6. software; you can redistribute it and/or modify it under the terms of
  7. the GNU Library General Public License as published by the Free
  8. Software Foundation; either version 2 of the License, or (at your
  9. option) any later version.  This library is distributed in the hope
  10. that it will be useful, but WITHOUT ANY WARRANTY; without even the
  11. implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
  12. PURPOSE.  See the GNU Library General Public License for more details.
  13. You should have received a copy of the GNU Library General Public
  14. License along with this library; if not, write to the Free Software
  15. Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
  16. */
  17. #ifdef __GNUG__
  18. #pragma implementation
  19. #endif
  20. #include <stdio.h>
  21. #include <stdarg.h>
  22. #include <builtin.h>
  23. #ifndef _OLD_STREAMS
  24. #include <strstream.h>
  25. #endif
  26. // Include CurseW.h and/or curses.h *after* iostream includes,
  27. // because curses.h defines a clear macro that conflicts with iostream. Sigh.
  28. #include <CursesW.h>
  29.  
  30. #if _G_HAVE_CURSES
  31.  
  32. int CursesWindow::count = 0;
  33.  
  34. /*
  35.  * C++ interface to curses library.
  36.  *
  37.  */
  38.  
  39. #if !defined(_IO_MAGIC) && !defined(HAVE_VSCANF) &&!defined vsscanf
  40. extern "C" int _doscan(FILE *, const char*, va_list args);
  41.  
  42. static int vsscanf(char *buf, const char * fmt, va_list args)
  43. {
  44.   FILE b;
  45. #ifdef _IOSTRG
  46.   b._flag = _IOREAD|_IOSTRG;
  47. #else
  48.   b._flag = _IOREAD;
  49. #endif
  50.   b._base = (unsigned char*)buf;
  51.   b._ptr = (unsigned char*)buf;
  52.   b._cnt = BUFSIZ;
  53.   return _doscan(&b, fmt, args);
  54. }
  55. #endif
  56.  
  57. /*
  58.  * varargs functions are handled conservatively:
  59.  * They interface directly into the underlying 
  60.  * _doscan, _doprnt and/or vfprintf routines rather than
  61.  * assume that such things are handled compatibly in the curses library
  62.  */
  63.  
  64. int CursesWindow::scanw(const char * fmt, ...)
  65. {
  66.   va_list args;
  67.   va_start(args, fmt);
  68. #ifdef VMS
  69.   int result = wscanw(w , fmt , args);
  70. #else /* NOT VMS */
  71.   char buf[BUFSIZ];
  72.   int result = wgetstr(w, buf);
  73.   if (result == OK) {
  74.  
  75. #ifdef _IO_MAGIC /* GNU iostreams */
  76.     strstreambuf ss(buf, BUFSIZ);
  77.     result = ss.vscan(fmt, args);
  78. #else
  79.     result = vsscanf(buf, fmt, args);
  80. #endif
  81.   }
  82. #endif /* !VMS */
  83.   va_end(args);
  84.   return result;
  85. }
  86.  
  87. int CursesWindow::mvscanw(int y, int x, const char * fmt, ...)
  88. {
  89.   va_list args;
  90.   va_start(args, fmt);
  91.   char buf[BUFSIZ];
  92.   int result = wmove(w, y, x);
  93.   if (result == OK)
  94. #ifdef VMS
  95.   result=wscanw(w , fmt , args);
  96. #else /* !VMS */
  97.  {
  98.     result = wgetstr(w, buf);
  99.     if (result == OK) {
  100. #ifdef _IO_MAGIC /* GNU iostreams */
  101.     strstreambuf ss(buf, BUFSIZ);
  102.     result = ss.vscan(fmt, args);
  103. #else
  104.     result = vsscanf(buf, fmt, args);
  105. #endif
  106.   }
  107.   }
  108. #endif /* !VMS */
  109.   va_end(args);
  110.   return result;
  111. }
  112.  
  113. int CursesWindow::printw(const char * fmt, ...)
  114. {
  115.   va_list args;
  116.   va_start(args, fmt);
  117.   char buf[BUFSIZ];
  118.   vsprintf(buf, fmt, args);
  119.   va_end(args);
  120.   return waddstr(w, buf);
  121. }
  122.  
  123.  
  124. int CursesWindow::mvprintw(int y, int x, const char * fmt, ...)
  125. {
  126.   va_list args;
  127.   va_start(args, fmt);
  128.   int result = wmove(w, y, x);
  129.   if (result == OK)
  130.   {
  131.     char buf[BUFSIZ];
  132.     vsprintf(buf, fmt, args);
  133.     result = waddstr(w, buf);
  134.   }
  135.   va_end(args);
  136.   return result;
  137. }
  138.  
  139. CursesWindow::CursesWindow(int lines, int cols, int begin_y, int begin_x)
  140. {
  141.   if (count==0)
  142.     initscr();
  143.  
  144.   w = newwin(lines, cols, begin_y, begin_x);
  145.   if (w == 0)
  146.   {
  147.     (*lib_error_handler)("CursesWindow", "Cannot construct window");
  148.   }
  149.  
  150.   alloced = 1;
  151.   subwins = par = sib = 0;
  152.   count++;
  153. }
  154.  
  155. CursesWindow::CursesWindow(WINDOW* &window)
  156. {
  157.   if (count==0)
  158.     initscr();
  159.  
  160.   w = window;
  161.   alloced = 0;
  162.   subwins = par = sib = 0;
  163.   count++;
  164. }
  165.  
  166. CursesWindow::CursesWindow(CursesWindow& win, int l, int c, 
  167.                            int by, int bx, char absrel)
  168. {
  169.  
  170.   if (absrel == 'r') // relative origin
  171.   {
  172.     by += win.begy();
  173.     bx += win.begx();
  174.   }
  175.  
  176.   // Even though we treat subwindows as a tree, the standard curses
  177.   // library needs the `subwin' call to link to the root in
  178.   // order to correctly perform refreshes, etc.
  179.  
  180.   CursesWindow* root = &win;
  181.   while (root->par != 0) root = root->par;
  182.  
  183.   w = subwin(root->w, l, c, by, bx);
  184.   if (w == 0)
  185.   {
  186.     (*lib_error_handler)("CursesWindow", "Cannot construct subwindow");
  187.   }
  188.  
  189.   par = &win;
  190.   sib = win.subwins;
  191.   win.subwins = this;
  192.   subwins = 0;
  193.   alloced = 1;
  194.   count++;
  195. }
  196.  
  197.  
  198. void CursesWindow::kill_subwindows()
  199. {
  200.   for (CursesWindow* p = subwins; p != 0; p = p->sib)
  201.   {
  202.     p->kill_subwindows();
  203.     if (p->alloced)
  204.     {
  205.       if (p->w != 0)
  206.         ::delwin(p->w);
  207.       p->alloced = 0;
  208.     }
  209.     p->w = 0; // cause a run-time error if anyone attempts to use...
  210.   }
  211. }
  212.     
  213. CursesWindow::~CursesWindow() 
  214. {
  215.   kill_subwindows();
  216.  
  217.   if (par != 0)   // Snip us from the parent's list of subwindows.
  218.   {
  219.     CursesWindow * win = par->subwins;
  220.     CursesWindow * trail = 0;
  221.     for (;;)
  222.     {
  223.       if (win == 0)
  224.         break;
  225.       else if (win == this)
  226.       {
  227.         if (trail != 0)
  228.           trail->sib = win->sib;
  229.         else
  230.           par->subwins = win->sib;
  231.         break;
  232.       }
  233.       else
  234.       {
  235.         trail = win;
  236.         win = win->sib;
  237.       }
  238.     }
  239.   }
  240.  
  241.   if (alloced && w != 0) 
  242.     delwin(w);
  243.  
  244.   --count;
  245.   if (count == 0) 
  246.     endwin();
  247.   else if (count < 0) // cannot happen!
  248.   {
  249.     (*lib_error_handler)("CursesWindow", "Too many windows destroyed");
  250.   }
  251. }
  252.  
  253. #endif /* _G_HAVE_CURSES */
  254.